package com.yeyks.hotel.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yeyks.common.ajax.AjaxResponseBody;
import com.yeyks.common.appcommon.dto.account.AppAccountDTO;
import com.yeyks.common.appcommon.dto.room.AppRoomCalendarDTO;
import com.yeyks.common.appcommon.param.room.AddRoomCalendarParam;
import com.yeyks.common.appcommon.param.room.CalendarDataParam;
import com.yeyks.common.appcommon.param.room.GetRoomCalendarParam;
import com.yeyks.common.appcommon.param.room.UpdateRoomCalendarParam;
import com.yeyks.common.appcommon.result.CommonResult;
import com.yeyks.common.constants.AccountType;
import com.yeyks.common.utils.DateUtils;
import com.yeyks.common.utils.apputil.bean.MyBeanUtils;
import com.yeyks.hotel.dal.dao.HotelInfoMapper;
import com.yeyks.hotel.dal.dao.RoomInfoMapper;
import com.yeyks.hotel.dal.domain.HotelInfo;
import com.yeyks.hotel.dal.domain.RoomCalendarInfo;
import com.yeyks.hotel.dal.dao.RoomCalendarInfoMapper;
import com.yeyks.hotel.dal.domain.RoomInfo;
import com.yeyks.hotel.param.UpdateRoomCalendarBatchParam;
import com.yeyks.hotel.service.RoomCalendarInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;


/**
 * <p>
 * 房间日历信息表 服务实现类
 * </p>
 *
 * @author yun
 * @since 2019-06-25
 */
@Service
@Slf4j
public class RoomCalendarInfoServiceImpl extends ServiceImpl<RoomCalendarInfoMapper, RoomCalendarInfo> implements RoomCalendarInfoService {

    @Autowired
    private RoomInfoMapper roomInfoMapper;

    @Autowired
    private RoomCalendarInfoMapper roomCalendarInfoMapper;

    @Autowired
    private HotelInfoMapper hotelInfoMapper;


    @Override
    @Transactional
    public void initRoomCalendar(RoomInfo roomInfo) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        Date startTime =  calendar.getTime();
        calendar.add(Calendar.DAY_OF_YEAR, 60);
        Date endTime =  calendar.getTime();
        List<RoomCalendarInfo> initCalendarInfoList = initCalendarInfoList(roomInfo);
        if (initCalendarInfoList!=null&&initCalendarInfoList.size()>0)
        {
            baseMapper.insertBatchCalendar(initCalendarInfoList);
        }
    }


    /**
     * 初始化30天房态信息
     *
     * @param roomInfo
     * @return
     */
    private List<RoomCalendarInfo> initCalendarInfoList(RoomInfo roomInfo) {
        List<RoomCalendarInfo> initCalendarInfoList = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);

        for (int i = 1; i <= 60; i++) {
            RoomCalendarInfo roomCalendarInfoNew = new RoomCalendarInfo();
            roomCalendarInfoNew.setHotelId(roomInfo.getHotelId());
            roomCalendarInfoNew.setRoomId(roomInfo.getId());
            roomCalendarInfoNew.setDate(calendar.getTime());
            roomCalendarInfoNew.setSalePrice(roomInfo.getCurPrice());
            roomCalendarInfoNew.setOriginPrice(roomInfo.getOrigPrice());
            roomCalendarInfoNew.setBottomPrice(null==roomInfo.getBottomPrice()?roomInfo.getCurPrice():roomInfo.getBottomPrice());
            roomCalendarInfoNew.setCount(roomInfo.getCount());
            roomCalendarInfoNew.setStatus(roomInfo.getValid()?1:0);
            //如果未找到房态记录则插入新的
            QueryWrapper<RoomCalendarInfo> queryWrapper = new QueryWrapper();
            queryWrapper.eq(RoomCalendarInfo.ROOM_ID,roomInfo.getId());
            queryWrapper.eq(RoomCalendarInfo.DATE,DateUtils.toYYMMddStr(calendar.getTime()));
            if(count(queryWrapper)==0)
            {
                initCalendarInfoList.add(roomCalendarInfoNew);
            }
            calendar.add(Calendar.DAY_OF_YEAR, 1);
        }
        return initCalendarInfoList;
    }

    @Override
    @Transactional
    public AjaxResponseBody updateRoomCalendar(RoomCalendarInfo roomCalendarInfo)
    {
        baseMapper.updateById(roomCalendarInfo);
        //如果是上架操作，则上架房间
        if(1==roomCalendarInfo.getStatus())
        {
            RoomInfo roomInfo = roomInfoMapper.selectByPrimaryKey(roomCalendarInfo.getRoomId());
            roomInfo.setValid(true);
            roomInfoMapper.updateByPrimaryKey(roomInfo);
        }
        return  AjaxResponseBody.success();
    }

    @Override
    public AjaxResponseBody updateRoomCalendarBatch(UpdateRoomCalendarBatchParam param) {

        List<CalendarDataParam> jsonData = JSONObject.parseArray(param.getCalendarData(),CalendarDataParam.class);
        List<RoomCalendarInfo> calendarInfoList = Lists.newArrayList();
        if (!CollectionUtils.isEmpty(jsonData)) {
            for (CalendarDataParam dataParam : jsonData) {
                RoomCalendarInfo roomCalendarInfo = new RoomCalendarInfo();
                roomCalendarInfo.setHotelId(param.getHotelId())
                        .setRoomId(param.getRoomId())
                        .setId(dataParam.getId())
                        .setDate(dataParam.getDate())
                        .setBottomPrice(dataParam.getBottomPrice())
                        .setSalePrice(dataParam.getSalePrice())
                        .setStatus(dataParam.getStatus())
                        .setCount(dataParam.getCount());
                calendarInfoList.add(roomCalendarInfo);
            }
        }
        if (!CollectionUtils.isEmpty(calendarInfoList)) {
            int count = roomCalendarInfoMapper.updateBatchCalendar(calendarInfoList);
            //上架操作则上架房间
            if(calendarInfoList.get(0).getStatus()==1)
            {
                RoomInfo roomInfo = roomInfoMapper.selectByPrimaryKey(param.getRoomId());
                roomInfo.setValid(true);
                roomInfoMapper.updateByPrimaryKey(roomInfo);
            }
            if (count > 0) {
                log.info("批量更新数据成功，更新行数为[{}]", count);
                return AjaxResponseBody.success("更新客房信息成功");
            }
        }
        return AjaxResponseBody.failed("更新客房信息失败");
    }

    //批量添加房间日期信息
    @Override
    public void createRoomCalendarInfoDo(List<RoomInfo> roomInfos) {
        //获取日期
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        //  起始日期
        Date startTime = calendar.getTime();
        calendar.add(Calendar.DAY_OF_YEAR, 60);
        //  截止日期(不包含)
        Date endTime = calendar.getTime();
        ArrayList<RoomCalendarInfo> roomCalendarInfoNews = new ArrayList<>();
        //排除不需要操作的room
        ArrayList<Integer> idList = new ArrayList<>();
        for (RoomInfo roomInfo : roomInfos) {
            idList.add(roomInfo.getId());
        }
        List<RoomCalendarInfo> roomCalendarInfos = baseMapper.selectForCreateRoomCalendarInfoDo(idList, startTime);
        Iterator<RoomInfo> iterator = roomInfos.iterator();
        while (iterator.hasNext()) {
            RoomInfo roomInfo = iterator.next();
            boolean flag = true;
            for (RoomCalendarInfo roomCalendarInfo : roomCalendarInfos) {
                if (roomCalendarInfo.getRoomId().equals(roomInfo.getId())) {
                    Date date = null;
                    date = roomCalendarInfo.getDate();
                    calendar.setTime(date);
                    calendar.add(Calendar.DAY_OF_YEAR, 1);
                    date = calendar.getTime();
                    //添加记录
                    createObject(calendar, endTime, roomCalendarInfoNews, roomInfo, date);
                    flag = false;
                    break;
                }
            }
            if (flag) {
                Date date = startTime;
                createObject(calendar, endTime, roomCalendarInfoNews, roomInfo, date);
            }
        }
        //批量添加
        if (roomCalendarInfoNews.size() > 0) {
            baseMapper.insertBatchCalendar(roomCalendarInfoNews);
            log.info("批量添加房态日历记录条数:"+roomCalendarInfoNews.size());
        }

    }

    private void createObject(Calendar calendar, Date endTime, ArrayList<RoomCalendarInfo> roomCalendarInfoNews, RoomInfo roomInfo, Date date) {
        //添加记录
        while (date.before(endTime)) {
            RoomCalendarInfo roomCalendarInfoNew = new RoomCalendarInfo();
            roomCalendarInfoNew.setHotelId(roomInfo.getHotelId());
            roomCalendarInfoNew.setRoomId(roomInfo.getId());
            roomCalendarInfoNew.setDate(date);
            roomCalendarInfoNew.setOriginPrice(roomInfo.getOrigPrice());
            roomCalendarInfoNew.setSalePrice(roomInfo.getCurPrice());
            roomCalendarInfoNew.setBottomPrice(roomInfo.getBottomPrice()==null?roomInfo.getCurPrice():roomInfo.getBottomPrice());
            roomCalendarInfoNew.setCount(roomInfo.getCount());
            roomCalendarInfoNew.setLockCount(0);
            roomCalendarInfoNew.setStatus(roomInfo.getValid()?1:0);
            //逐条生成记录
            //roomCalendarInfoMapper.insert(roomCalendarInfoNew);
            roomCalendarInfoNews.add(roomCalendarInfoNew);
            calendar.setTime(date);
            calendar.add(Calendar.DAY_OF_YEAR, 1);
            date = calendar.getTime();
        }
    }

    @Override
    public List<RoomCalendarInfo> selectRoomCalendar(Integer roomId) {
        Calendar calendar = Calendar.getInstance();
        //  起始日期
        Date startTime = calendar.getTime();
        calendar.add(Calendar.DAY_OF_YEAR, 30);
        //  截止日期(不包含)
        Date endTime = calendar.getTime();
        QueryWrapper<RoomCalendarInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(RoomCalendarInfo::getRoomId, roomId)
                .ge(RoomCalendarInfo::getDate, DateUtils.formatDate(startTime))
                .le(RoomCalendarInfo::getDate, DateUtils.formatDate(endTime));

        List<RoomCalendarInfo> RoomCalendarInfoList = list(queryWrapper);
        return RoomCalendarInfoList;
    }


    //==============================admin-app 相关接口实现 ==============================

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult addRoomCalendar(AddRoomCalendarParam param, AppAccountDTO accountDTO) {

        //得到当前酒店的ID
        if (accountDTO.getManagerId() != null) {
            accountDTO.setId(accountDTO.getManagerId());
        }
        HotelInfo hotelInfo = hotelInfoMapper.selectHotelInfoByOperatorId(accountDTO.getId());
        List<CalendarDataParam> jsonData;
        List<RoomCalendarInfo> calendarInfoList = Lists.newArrayList();
        if (null != hotelInfo) {
            //查询房间的原价
            RoomInfo roomInfo = roomInfoMapper.selectByPrimaryKey(param.getRoomId());
            //组装30天数据信息
            if (!StringUtils.isEmpty(param.getCalendarData())) {
                jsonData = JSONObject.parseArray(param.getCalendarData(), CalendarDataParam.class);
            }else{
                jsonData = convertOneMonth(roomInfo);
            }
            for (CalendarDataParam dataParam : jsonData) {
                Map<String, Object> params = Maps.newHashMap();
                params.put(RoomCalendarInfo.ROOM_ID, param.getRoomId());
                params.put(RoomCalendarInfo.DATE, dataParam.getDate());
                RoomCalendarInfo selectCalendar = roomCalendarInfoMapper
                        .selectOne(new QueryWrapper<RoomCalendarInfo>().allEq(params));
                if (null != selectCalendar) {
                    continue;
                }
                RoomCalendarInfo roomCalendarInfo = new RoomCalendarInfo();
                roomCalendarInfo.setHotelId(hotelInfo.getId())
                        .setRoomId(param.getRoomId())
                        .setDate(dataParam.getDate())
                        .setBottomPrice(dataParam.getBottomPrice())
                        .setSalePrice(dataParam.getSalePrice())
                        .setStatus(dataParam.getStatus())
                        .setLockCount(0)
                        .setCount(dataParam.getCount())
                        .setOriginPrice(roomInfo.getOrigPrice());
                calendarInfoList.add(roomCalendarInfo);
            }
        }
        if (!CollectionUtils.isEmpty(calendarInfoList)) {
            //执行批量添加信息
            int count = roomCalendarInfoMapper.insertBatchCalendar(calendarInfoList);
            if (count > 0) {
                return CommonResult.success(null, "客房新建成功");
            }
        }
        return CommonResult.failed("客房新建失败");
    }

    /**
     * 组装60天的房态数据进行添加
     * @param roomInfo 客房信息
     * @return 返回结合结果
     */
    private List<CalendarDataParam> convertOneMonth(RoomInfo roomInfo) {

        List<CalendarDataParam> calendarDataParamList = Lists.newArrayList();
        for (int i = 0; i < 60; i++) {
            String date = DateUtils.getDateForDay(i);
            CalendarDataParam param = new CalendarDataParam();
            param.setDate(DateUtils.yyyyMMddToDate(date));
            param.setBottomPrice(roomInfo.getBottomPrice());
            param.setSalePrice(roomInfo.getCurPrice());
            param.setCount(roomInfo.getCount());
            param.setStatus(1);
            calendarDataParamList.add(param);
        }
        return calendarDataParamList;
    }


    @Override
    public CommonResult<List<AppRoomCalendarDTO>> getRoomCalendar(GetRoomCalendarParam param, AppAccountDTO accountDTO) {

        List<AppRoomCalendarDTO> calendarDTOList = Lists.newLinkedList();
        RoomInfo roomInfo = roomInfoMapper.selectByPrimaryKey(param.getRoomId());
        List<RoomCalendarInfo> calendarInfoList = roomCalendarInfoMapper.selectFutureOneMonthDataByRoomId(param.getRoomId());
        if (!CollectionUtils.isEmpty(calendarInfoList)) {
            calendarInfoList.forEach(calendarInfo -> {
                if (null == calendarInfo.getBottomPrice() && null == roomInfo.getBottomPrice()) {
                    calendarInfo.setBottomPrice(roomInfo.getCurPrice());
                }else if(null == calendarInfo.getBottomPrice()){
                    calendarInfo.setBottomPrice(roomInfo.getBottomPrice());
                }
            });
            log.info("该房间ID为[{}]的数据查询正常！", param.getRoomId());
            calendarDTOList = MyBeanUtils.convertArrayList(calendarInfoList, AppRoomCalendarDTO.class);

        }
        return CommonResult.success(calendarDTOList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult updateRoomCalendar(UpdateRoomCalendarParam param, AppAccountDTO accountDTO) {

        //得到当前酒店的ID
        if (accountDTO.getManagerId() != null) {
            accountDTO.setId(accountDTO.getManagerId());
        }
        HotelInfo hotelInfo = hotelInfoMapper.selectHotelInfoByOperatorId(accountDTO.getId());
        List<RoomCalendarInfo> updateCalendarInfoList = Lists.newArrayList();
        List<CalendarDataParam> jsonData = JSONObject.parseArray(param.getCalendarData(), CalendarDataParam.class);

        if (null != hotelInfo) {
            if (!CollectionUtils.isEmpty(jsonData)) {
                for (CalendarDataParam dataParam : jsonData) {
                    RoomCalendarInfo roomCalendarInfo = new RoomCalendarInfo();
                    roomCalendarInfo.setHotelId(hotelInfo.getId())
                            .setRoomId(param.getRoomId())
                            .setId(dataParam.getId())
                            .setDate(dataParam.getDate())
                            .setBottomPrice(dataParam.getBottomPrice())
                            .setSalePrice(dataParam.getSalePrice())
                            .setStatus(dataParam.getStatus())
                            .setCount(dataParam.getCount());
                    updateCalendarInfoList.add(roomCalendarInfo);
                }
            }
        }
        if (!CollectionUtils.isEmpty(updateCalendarInfoList)) {
            //执行批量添加信息
            int count = roomCalendarInfoMapper.updateBatchCalendar(updateCalendarInfoList);
            if (count > 0) {
                log.info("批量更新数据成功，更新行数为[{}]", count);
                return CommonResult.success(null, "更新客房信息成功");
            }
        }
        return CommonResult.failed("更新客房信息失败");
    }

    /**
     * 修改房态状态
     *
     * @param id
     * @param status
     */
    @Override
    public int updateRoomCalendarStatus(Integer id, int status) {
        return baseMapper.updateRoomCalendarStatus(id, status);
    }

    /**
     * 修改房态状态
     *
     * @param ids
     * @param status
     */
    @Override
    public Boolean updateRoomCalendarStatusList(List<Integer> ids, int status) {
        return baseMapper.updateRoomCalendarStatusList(ids, status) == ids.size();
    }
}
